package com.ll.servlet;

import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.WsOutbound;

public class WebChatServer
{
	public static WebChatServer instance = new WebChatServer();
	

	private List<MessageInbound> service_inbound  = new ArrayList<MessageInbound>();
	private List<String>         service_username = new ArrayList<String>();
	
	private List<MessageInbound> visitor_inbound  = new ArrayList<MessageInbound>();
	private List<String>         visitor_username = new ArrayList<String>();

	private long visitor_id = 0;
	
	private WebChatServer()
	{
	}
	
	public static WebChatServer getInstance()
	{
		return instance;
	}
	
	//客服注册
	public void registMessageInbound(String username, MessageInbound inbound)
		throws Exception
	{
		//发送客服列表
		List<String> userlist = new ArrayList<String>();
		userlist.addAll(service_username);
		userlist.addAll(visitor_username);
		this.sendUserList(userlist, inbound);
		
		//通知其他已登录用户
		List<MessageInbound> inboundlist = new ArrayList<MessageInbound>();
		inboundlist.addAll(service_inbound);
		inboundlist.addAll(visitor_inbound);
		this.notifyLogin(username, inboundlist);
					
		service_inbound.add(inbound);
		service_username.add(username);

		System.out.println("[WebChatServer] registMessageInbound, username:" + username 
				+ ", inbound:" + inbound.hashCode());
	}
	
	//游客注册
	public void registMessageInbound(MessageInbound inbound)
		throws Exception
	{
		//为游客生成用户名 暂时不考虑和客服重名的问题
		String username = "visitor" + visitor_id++;
		
		
		this.visitor_username.add(username);
		this.visitor_inbound.add(inbound);
		
		//通知其他已登录用户
		this.notifyLogin(username, service_inbound);
	}
	
	public void releaseMessageInbound(MessageInbound inbound)
		throws Exception
	{
		//需要通知的用户列表
		List<MessageInbound> notifyInboundlist = new ArrayList<MessageInbound>();
		String exitID = null;
		
		
		int index = service_inbound.indexOf(inbound);
		if(-1 != index && index < service_inbound.size()) 
		{
			//客服注销
			exitID = service_username.get(index);
			service_inbound.remove(index);
			service_username.remove(index);
			
			//客服注销，通知所有人
			notifyInboundlist.addAll(service_inbound);
			notifyInboundlist.addAll(visitor_inbound);
		} 
		else 
		{
			//游客注销
			index = visitor_inbound.indexOf(inbound);
			if(-1 != index && index < visitor_inbound.size())
			{
				exitID = visitor_username.get(index);
				visitor_inbound.remove(index);
				visitor_username.remove(index);
				
				//游客注销, 通知客服
				notifyInboundlist.addAll(service_inbound);
			}
		}

		System.out.println("[WebChatServer] visitor exit: " + exitID);
		//通知其他用户该用户离线
		this.notifyExit(exitID, notifyInboundlist);
	}

	
	public void onGetMsg(JSONObject jo) throws Exception
	{
		System.out.println("[WebChatServer] in get textmsg...");
		
		if(jo == null) return;
		String toUsername = jo.getString("toUsername");
		
		MessageInbound toInbound = null;
		int index = -1;
		for(int i = 0; i < this.service_username.size(); i++)
		{
			if(toUsername.equals(this.service_username.get(i)))
			{
				index = i;
				break;
			}
		}
		
		if(-1 != index) 
			toInbound = this.service_inbound.get(index);
		else
		{
			for(int i = 0; i < this.visitor_username.size(); i++)
			{
				if(toUsername.equals(this.visitor_username.get(i)))
				{
					index = i;
					break;
				}
			}
			
			if(-1 != index)
				toInbound = this.visitor_inbound.get(index);
		}
		
		if(toInbound != null)
		{
			toInbound.getWsOutbound().writeTextMessage(CharBuffer.wrap(jo.toString()));	
		}
	}
	
	public void reqServiceList(MessageInbound inbound)
		throws Exception
	{
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("action", "servicelist");
		m.put("servicelist", this.service_username.toArray());
		JSONObject jo = JSONObject.fromObject(m);
		inbound.getWsOutbound().writeTextMessage(CharBuffer.wrap(jo.toString()));
	}
	
	private void sendUserList(List<String> list, MessageInbound inbound)
		throws Exception
	{
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("action", "userlist");
		m.put("userlist", list);
		JSONObject jo = JSONObject.fromObject(m);
		inbound.getWsOutbound().writeTextMessage(CharBuffer.wrap(jo.toString()));
	}
	
	private void notifyLogin(String username, List<MessageInbound> inboundlist)
		throws Exception
	{
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("action", "loginUser");
		m.put("username", username);
		JSONObject jo = JSONObject.fromObject(m);
		
		for(int i = 0; i < inboundlist.size(); i++)
		{
			WsOutbound out = inboundlist.get(i).getWsOutbound();
			out.writeTextMessage(CharBuffer.wrap(jo.toString()));
		}
	}
	
	private void notifyExit(String username, List<MessageInbound> inboundlist)
		throws Exception
	{
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("action", "exitUser");
		m.put("username", username);
		JSONObject jo = JSONObject.fromObject(m);
		
		for(int i = 0; i < inboundlist.size(); i++)
		{
			WsOutbound out = inboundlist.get(i).getWsOutbound();
			out.writeTextMessage(CharBuffer.wrap(jo.toString()));
		}
	}
}
